package com.itheima.d4_collection_set;

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

/**
 * 目标：掌握TreeSet集合的使用。

 * 特点：不重复、无索引、可排序（默认升序排序 ，按照元素的大小，由小到大排序）
 * 底层是基于红黑树实现的排序。（遍历方式是左根右，中序遍历）
 *
 * 注意：
 * 对于数值类型：Integer , Double，默认按照数值本身的大小进行升序排序。
 * 对于字符串类型：默认按照首字符的编号升序排序。
 * 对于自定义类型如Student对象，TreeSet默认是无法直接排序的。
 *
 * 自定义排序规则：
 * TreeSet集合存储自定义类型的对象时，必须指定排序规则，支持如下两种方式来指定比较规则。
 * 方式一
 *      让自定义的类（如学生类）实现Comparable接口，重写里面的compareTo方法来指定比较规则。
 * 方式二
 *      public TreeSet(Comparator<? super E> comparator)
 *      通过调用TreeSet集合有参数构造器，可以设置Comparator对象（比较器对象，用于指定比较规则。
 *
 * 注意：如果类本身有实现Comparable接口，TreeSet集合同时也自带比较器，默认使用集合自带的比较器排序。
 */
/*
两种方式中，关于返回值的规则：
如果认为第一个元素 >  第二个元素 返回正整数即可。
如果认为第一个元素 < 第二个元素返回负整数即可。
如果认为第一个元素 = 第二个元素返回0即可，此时Treeset集合只会保留一个元素，认为两者重复。
 */

/*
Collection集合特点:单列集合接口，有两个子接口--List和Set
    List系列集合：添加的元素是有序、可重复、有索引。
        常用实现类：ArrayList、LinekdList ：有序、可重复、有索引。
    Set系列集合：添加的元素是无序、不重复、无索引。
        HashSet: 无序、不重复、无索引；
        LinkedHashSet: 有序、不重复、无索引。
        TreeSet：按照大小默认升序排序、不重复、无索引。

1、如果希望记住元素的添加顺序，需要存储重复的元素，又要频繁的根据索引查询数据？
用ArrayList集合（有序、可重复、有索引），底层基于数组的。（常用）
2、如果希望记住元素的添加顺序，且增删首尾数据的情况较多？
用LinkedList集合（有序、可重复、有索引），底层基于双链表实现的。
3. 如果不在意元素顺序，也没有重复元素需要存储，只希望增删改查都快？
用HashSet集合（无序，不重复，无索引），底层基于哈希表实现的。 （常用）
4. 如果希望记住元素的添加顺序，也没有重复元素需要存储，且希望增删改查都快？
用LinkedHashSet集合（有序，不重复，无索引）， 底层基于哈希表和双链表。
5. 如果要对元素进行排序，也没有重复元素需要存储？且希望增删改查都快？
用TreeSet集合，基于红黑树实现。


 */
public class SetTest4 {
    public static void main(String[] args) {
        Set<Integer> set1 = new TreeSet<>();
        set1.add(6);
        set1.add(5);
        set1.add(5);
        set1.add(7);
        set1.add(1);
        set1.add(3);
        System.out.println(set1);

        //Set<Student> students = new TreeSet<>();
        //在Day04里面的d5array的sort排序方法，讲过类似的。视频126集。package com.itheima.d5_arrays;
        // TreeSet就近选择自己自带的比较器对象进行排序
/*
        Set<Student> students = new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                  // 如果认为左边对象大于右边对象返回正整数
                  // 如果认为左边对象小于右边对象返回负整数
                 // 如果认为左边对象等于右边对象返回0，此时treeSet集合只会保留第一个元素，认为两者重复
                // 需求：按照身高升序排序
                return Double.compare(o1.getHeight() , o2.getHeight());
            }
        });
        */

        /*
        compare源码：
        public static int compare(double d1, double d2) {
        if (d1 < d2)
            return -1;
        if (d1 > d2)
            return 1;
         */
        //treeSet集合是一定要对集合中的元素进行排序，否则会报错
        Set<Student> students = new TreeSet<>(( o1,  o2) ->  Double.compare(o1.getHeight() , o2.getHeight()));

        students.add(new Student("蜘蛛精",23, 169.7));
        students.add(new Student("紫霞",22, 169.8));
        students.add(new Student("至尊宝",26, 165.5));
        students.add(new Student("牛魔王",22, 183.5));
        System.out.println(students);
    }
}
